const express = require('express');
const cors = require('cors');
require('dotenv').config();
const cluster = require('cluster');
const logger = require('../../utils/logger');
const os = require('os');
const timeoutHandler = require('express-timeout-handler');
const func_rs = require("./rs");
const func_boss = require("./boss");


const app = express();
const PORT = process.env.PORT || 53000;
// Node.js是单线程的，但可以使用集群模式来利用多核CPU。可以使用cluster模块来实现
if (cluster.isMaster) {
    const numCPUs = os.cpus().length;
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }

    cluster.on('exit', (worker, code, signal) => {
        console.log(`Worker ${worker.process.pid} died`);
        cluster.fork();
    });
} else {
    // Middleware
    app.use(cors());
    app.use(express.json({ limit: '50mb' })); // Adjust limit as needed
    app.use(express.urlencoded({ limit: '50mb', extended: true }));

    // Timeout configuration
    const timeoutOptions = {
        timeout: 5000, // 5 seconds
        onTimeout: (req, res) => {
            res.status(503).json({
                    "code": 503,
                    "data": null,
                    "cost": `5000ms`,
                    "msg": `Service unavailable. Please retry later.`
                });
        },
        onDelayedResponse: (req, method, args, requestTime) => {
            console.warn(`Request for ${req.url} exceeded timeout of ${requestTime}ms`);
        },
        disable: ['write', 'setHeaders', 'send', 'json', 'end'],
    };

    app.use(timeoutHandler.handler(timeoutOptions));

    // Routes
    app.get('/', (req, res) => {
        res.send('Hello World');
    });

    app.post('/rs6', (req, res) => {
        const startTime = new Date().getTime();
        const url = req.body.url;
        const htmltext = req.body.htmltext;
        const jstext = req.body.jstext;
        const cookie_dict = req.body.cookie_dict;
        logger.debug(`url -> ${url}`);
        logger.debug(`cookie_dict -> ${JSON.stringify(cookie_dict)}`);
        try {
            func_rs(url, htmltext, jstext, cookie_dict, res, startTime);
        } catch (error) {
            logger.error(error);
            res.status(400).json({
                "code": 400,
                "data": null,
                "cost": `${new Date().getTime() - startTime}ms`,
                "msg": `Invalid request ${error}`
            });
        }
    });

    app.post('/boss', (req, res) => {
        const startTime = new Date().getTime();
        const url = req.body.url;
        const htmltext = req.body.htmltext;
        const jstext = req.body.jstext;
        const cookie_dict = req.body.cookie_dict;
        logger.debug(`url -> ${url}`);
        logger.debug(`cookie_dict -> ${JSON.stringify(cookie_dict)}`);
        try {
            func_boss(url, htmltext, jstext, cookie_dict, res, startTime);
        } catch (error) {
            logger.error(error);
            res.status(400).json({
                "code": 400,
                "data": null,
                "cost": `${new Date().getTime() - startTime}ms`,
                "msg": `Invalid request ${error}`
            });
        }
    });

    app.listen(PORT, () => {
        console.log(`Worker ${process.pid} is running on port ${PORT}`);
    });
}
